#include "library/putchar.bas"
#include "library/charmapsudgsulaplus.bas"
#include "library/ulaplus.bas"

'- solitario - jun'05,oct'11 - paulo silva - rev 20111112190458
'- for the csscgc2011 competition, hosted by mojon twins
'- based on the msx version for the karoshi's msxbasic competition at winter'06

debug=0

ulaplusswitch(1):cls
for jv=0 to 63 step 16
for iv=0 to 15
  ulapluspalette(iv+jv,peek(@ulapluspalette1+iv))
  next:next
for jv=8 to 63 step 32
for iv=0 to 15
  ulapluspalette(iv+jv,peek(@ulapluspalette1+iv))
  next:next

gamestartup: '----- game system startup -----
border 0:paper 7:ink 0:bright 0:cls
dim i,x,y,ch,se,sl,pf,gv,pa,je,ka,cn,tf,tt as integer
dim px,py,ox,oy,dx,dy,x1,y1,x2,y2 as integer
dim mx,my as float

dim a(7,7) as integer
dim t(10) as long
dim u$(10):dim r$(10)

'-----  some game arrays

dim h$(10)
h$(0)="PORCOROSSO":h$(1)="TOTORO":h$(2)="CHIHIRO":h$(3)="HEIDI":h$(4)="KONAN"
h$(5)="GHIBLI":h$(6)="MONONOKE":h$(7)="NAUSICAA":h$(8)="LUPIN":h$(9)="UNKNOWN"

dim qa(9) as ubyte => {2,2,3,4,4,4,5,5,7,9}
dim qb(9) as ubyte => {108,128,119,104,106,111,105,117,141,112}

for i=0 to 9
  let t(i)=(qa(i)*72000)+(qb(i)*60)
  let r$(i)=str$(qa(i))
  next i
for i=0 to 9
  let u$(i)=chr$(int(t(i)/36000)mod 2+48)+chr$(int(t(i)/3600)mod 10+48)+chr$(39)
  let u$(i)=u$(i)+chr$(int(t(i)/600)mod 6+48)+chr$(int(t(i)/60)mod 10+48)+chr$(34)
  next i

gametitle: '----- game title --------------
cls
poke uinteger 23672,0
if ch=1 then:print at 0,0;"!":end if

print at 12,3;"BY PAULO SILVA, '05,'11"
print at 21,3;"PUSH SPACE KEY"

let zu$=    "...........X.X..........X......."
let zu$=zu$+"...XXX.....X...X................"
let zu$=zu$+"...X...XXX.X.X.XX.XX.XX.X.XXX..."
let zu$=zu$+"...XXX.X.X.X.X.X...X.X..X.X.X..."
let zu$=zu$+".....X.X.X.X.X.X.XXX.X..X.X.X..."
let zu$=zu$+"...XXX.XXX.X.X.XXXXX.X..X.XXX..."

print at 14,0;
for i=0 to len(zu$)-1
  if zu$(i)="." then:print ink 0;paper 5;bright 1;"\A";:end if
  if zu$(i)<>"." then:print ink 2;paper 5;bright 1;"\B";:end if
  next i

gametitledelay:
if inkey$=" " then: goto gameplay:end if
if peek(uinteger,23672) < 600 then: goto gametitledelay:end if

scoretable: '----- score table -------------
cls
poke uinteger 23672,0
print at 9,4;"HISCORES     REST TIME"
if ch=1 then:print at 0,0;"!": end if

scoretabledelay:
let i=int(peek(uinteger,23672)/15)-1
if i>=0 and i<10 then:
  print at i+11,4;h$(i)
  print at i+11,17;r$(i)
  print at i+11,22;u$(i)
  end if

if inkey$<>"" or peek(uinteger,23672)>=600 then: goto gametitle:end if
goto scoretabledelay

gameplay: '----- game play ---------------
cls
poke uinteger 23672,0
if ch=1 then:print at 0,0;"!":end if

drawingbackground: '- drawing background ----------------------
let sx=6
let sy=6
let vp=sx+(sy*32)
for y=0 to 3:  print at y+sy-1,sx+3;paper 5;bright 1;"       ";:next y
for y=4 to 10: print at y+sy-1,sx-1;paper 5;bright 1;"               ";:next y
for y=11 to 14:print at y+sy-1,sx+3;paper 5;bright 1;"       ";:next y
print at 5,22;"TIME"
print at 8,22;"REST"

gosub restartboard

let px=3
let py=3

let ox=3
let oy=3
let se=0
let sl=0
let pf=0
gosub arraytodisplay
gosub restartboard
let pf=1
gosub arraytodisplay
let gv=0
let pa=32
let je=0
poke uinteger 23672,0
let tt=peek(uinteger,23672)
gosub displaytimer

kprs=0

let x1=0
let y1=0
let x2=6
let y2=6

gameloop:   '- game loop -----------------------
pause 1

stick=((255-(in 64510)) band 2)/2 bor ((255-(in 65022)) band 2) bor ((255-(in 65022)) band 1)*4 bor ((255-(in 65022)) band 4)*2
stick=stick bor ((255-(in 61438)) band 8)/8 bor ((255-(in 61438)) band 16)/8 bor ((255-(in 63486)) band 16)/4 bor ((255-(in 61438)) band 4)*2

if je=1 and stick=0 then:let je=0:end if
if je=0 and stick<>0 then:
  gosub cursormotion
  end if

ink 1:paper 5:bright 1
print at sy+(py*2)-1,sx+(px*2)-1;"\C\D\E":print at sy+(py*2),sx+(px*2)-1;"\F"
print at sy+(py*2),sx+(px*2)+1;"\G":print at sy+(py*2)+1,sx+(px*2)-1;"\H\I\J"
ink 0:paper 7:bright 0

rem --- updating time display --- :let sq=sti(0) -?
let qq=tt
let tt=peek(uinteger,23672)
if (int(qq/60))<>(int(tt/60)) then:gosub displaytimer:end if

if inkey$=" " and se=0 then:let se=1:gosub refreshandcheck:end if
if inkey$<>" " then:let se=0:end if

if inkey$=chr$(27) then:goto scorewrite:end if
if gv=1 then gosub gameover:goto scorewrite:end if
goto gameloop

refreshandcheck:   '- some display refresh and check? ---
if sl=0 and a(px,py)=1 then:
  let a(px,py)=2
  let ox=px
  let oy=py
  let sl=1
  print at (py*2)+sy,(px*2)+sx;ink 6;paper 5;bright 1;"\B"
  return
  end if
if sl=1 and a(px,py)=2 then:
  let a(px,py)=1
  let ox=px
  let oy=py
  let sl=0
  print at (py*2)+sy,(px*2)+sx;ink 2;paper 5;bright 1;"\B"
  return
  end if
let dx=abs(px-ox)
let dy=abs(py-oy)
let mx=(ox+px)/2
let my=(oy+py)/2
let zz=((dx=0 and dy=2) and (a(mx,my)=1)) or ((dx=2 and dy=0) and (a(mx,my)=1))
if sl=1 and a(px,py)=0 then:
  if zz then:
    let a(mx,my)=0
    let a(ox,oy)=0
    let a(px,py)=1
    let sl=0
    print at (my*2)+sy,(mx*2)+sx;ink 0;paper 5;bright 1;"\A"
    print at (oy*2)+sy,(ox*2)+sx;ink 0;paper 5;bright 1;"\A"
    print at (py*2)+sy,(px*2)+sx;ink 2;paper 5;bright 1;"\B"
    let pa=pa-1
    gosub checkpossiblemotions
    gosub displaytimer
    end if
  end if
return

gameover: '- game over - some delay before writing name --------------------------
poke uinteger 23672,0
print at 18,22;"NO MORE":print at 19,22;"MOVES!"
gameoverdelay:
if peek(uinteger,23672)<200 then
  goto gameoverdelay
  end if
return

restartboard:  '- restarting the board array values (i must check if its true) -------------------------
for y=0 to 6:for x=0 to 6
  let a(x,y)=1
  next x:next y
for y=5 to 8:for x=5 to 8
  let a((x mod 7),(y mod 7))=3
  next x:next y
let a(3,3)=0:return

arraytodisplay: '- i forgot what this does --- transfers array pieces to display? -------------------------------
for y=0 to 6:for x=0 to 6
  if a(x,y)<3 then:
    print at (y*2)+sy,(x*2)+sx;ink 0;paper 5;bright 1;"\A" :'- <- verificar udg,ink,paper,bright
    end if
  if a(x,y)<3 and pf=1 then:
    if a(x,y)=0 then:print at (y*2)+sy,(x*2)+sx;ink 0;paper 5;bright 1;"\A":end if
    if a(x,y)=1 then:print at (y*2)+sy,(x*2)+sx;ink 2;paper 5;bright 1;"\B":end if
    if a(x,y)>1 then:print at (y*2)+sy,(x*2)+sx;ink 6;paper 5;bright 1;"\B":end if
    end if
  next x:next y
return

cursormotion: '- cursor motion -----------------------------------------
let je=1

stick=((255-(in 64510)) band 2)/2 bor ((255-(in 65022)) band 2) bor ((255-(in 65022)) band 1)*4 bor ((255-(in 65022)) band 4)*2
stick=stick bor ((255-(in 61438)) band 8)/8 bor ((255-(in 61438)) band 16)/8 bor ((255-(in 63486)) band 16)/4 bor ((255-(in 61438)) band 4)*2

'- verificar os valores de stick

'--- erase sprite ------
ink 1:paper 5:bright 1   :' <---- verificar
print at sy+(py*2)-1,sx+(px*2)-1;"   ":print at sy+(py*2),sx+(px*2)-1;" "
print at sy+(py*2),sx+(px*2)+1;" ":print at sy+(py*2)+1,sx+(px*2)-1;"   ";
ink 0:paper 7:bright 0

if debug=1 then:print at 1,1;"PX:";px;",PY:";py;" ":end if : pause 1: rem <- debug -----

kprs=0 :'- <---

if kprs=0 and stick=1 then: kprs=1:py=py-1:end if
if kprs=0 and stick=2 then: kprs=1:py=py+1:end if
if kprs=0 and stick=4 then: kprs=1:px=px-1:end if
if kprs=0 and stick=8 then: kprs=1:px=px+1:end if
'if kprs<>0 and stick=0 then:kprs=0:end if :'- <--???? manter?

if px<x1 then:px=x2:end if
if px>x2 then:px=x1:end if
if py<y1 then:py=y2:end if
if py>y2 then:py=y1:end if

y1=0:y2=6:x1=0:x2=6
if px<2 then:x1=0:x2=6:y1=2:y2=4:end if
if px>4 then:x1=0:x2=6:y1=2:y2=4:end if
if py<2 then:y1=0:y2=6:x1=2:x2=4:end if
if py>4 then:y1=0:y2=6:x1=2:x2=4:end if

if debug=1 then:print at 1,1;"PX:";px;",PY:";py;" ":end if : rem <- debug -----
if debug=1 then:print at 2,1;"SX:";sx;",SY:";sy;" ":end if : rem <- debug -----
if debug=1 then:print at 3,1;"OX:";ox;",OY:";oy;" ":end if : rem <- debug -----
if debug=1 then:print at 1,11;"X1:";x1;",Y1:";y1;" ":end if : rem <- debug -----
if debug=1 then:print at 2,11;"X2:";x2;",Y2:";y2;" ":end if : rem <- debug -----
if debug=1 then:print at 3,11;stick;"  ":end if : rem <- debug -----

return

checkpossiblemotions:  '- checking for possible motions ---------------------------------
if ch=1 then:return:end if
let ck=0
print at 19,22;"WAIT..."
for x=2 to 4:for y=0 to 4
  let v1=a(x,y)*4+a(x,y+1)*2+a(x,y+2)
  let v2=a(y,x)*4+a(y+1,x)*2+a(y+2,x)
  if v1=3 or v1=6 or v2=3 or v2=6 then:let ck=ck+1:end if
  next y:next x
for x=5 to 8:
  let xm=x mod 7
  let v1=a(x,2)*4+a(x,3)*2+a(x,4)
  let v2=a(2,x)*4+a(3,x)*2+a(4,x)
  if v1=3 or v1=6 or v2=3 or v2=6 then:let ck=ck+1:end if
  next x
if ck=0 then:let gv=1:end if

if debug=1 then: print at 0,0;"CK:";ck;",GV:";gv;".": end if: rem -> debug!

rem ck=at least possible motions, gv=game over on
print at 19,22;"       "
return

displaytimer: '- displaying timer -----------------------------------
let qq=tt
let tt=peek(uinteger,23672)
let k$=chr$(int(tt/36000)mod 2+48)+chr$(int(tt/3600)mod 10+48)+chr$(39)
let k$=k$+chr$(int(tt/600)mod 6+48)+chr$(int(tt/60)mod 10+48)+chr$(34)
print at 6,23;k$
print at 9,23;str$(pa);" "
return

scorewrite: '----- score write ------------------------------------
cls
poke uinteger 23672,0
let l$=""
if ch=1 then:print at 0,0;"!":end if
let tf=tt+(pa*72000)
rem if cn=0 then:goto scoretable:end if
print at 9,4;"YOUR NAME:"

textinput: '- text input loop ---------------------------------
let k$=inkey$
let kl=len(k$)
let ka=code(k$)
if ka>31 and ka<96 and len(l$)<10 then:let l$=l$+k$:end if
if ka>95 and ka<127 and len(l$)<10 then:let l$=l$+chr$(code(k$)-32):end if

if (ka=8 or ka=29) and len(l$)>0 then
  'let l$=left$(l$,len(l$)-1)
  let l$=l$(to len(l$)-1)
  end if

if ka=13 then:goto 5200:end if

print at 11,4;l$;"   ":
print at 20,4;"TIME:";29-int(peek(uinteger,23672)/60);"  "

rem putsprite 0,(28+len(l$)*8,84),7,0 <- substituir por 8 udgs
'ink 1:paper 5:bright 1
'print at sy+(py*2)-1,sx+(px*2)-1;"\C\D\E":print at sy+(py*2),sx+(px*2)-1;"\F"
'print at sy+(py*2),sx+(px*2)+1;"\G":print at sy+(py*2)+1,sx+(px*2)-1;"\H\I\J"
'ink 0:paper 7:bright 0

if peek(uinteger,23672)<1790 then:goto textinput:end if

'- finding hiscore hole for current score -
5200:
let iq=10
for i=9 to 0 step -1
if tf<t(i) then:let iq=iq-1:end if
next i
if iq>9 then:goto scoretable:end if

'- moving worse scores down -
5300:
for i=8 to iq step -1:let h$(i+1)=h$(i):let u$(i+1)=u$(i):let t(i+1)=t(i):let r$(i+1)=r$(i):next i
let h$(iq)=l$:let t(iq)=tf:let r$(iq)=str$(pa)
let u$(iq)=chr$(int(t(iq)/36000)mod 2+48)
let u$(iq)=u$(iq)+chr$(int(t(iq)/3600)mod 10+48)+chr$(39)
let u$(iq)=u$(iq)+chr$(int(t(iq)/600)mod 6+48)
let u$(iq)=u$(iq)+chr$(int(t(iq)/60)mod 10+48)
let u$(iq)=u$(iq)+chr$(34)
goto scoretable



'----- end of game -------------




